//
//  flags.m
//  test
//
//  Created by Holmes Futrell on 11/13/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "GLTexture.h"
#import "common.h"

@implementation GLTexture

@synthesize descriptor, width, height, internalWidth, internalHeight;

- (unsigned int)enableDefaultFlags:(unsigned int)flags {
	if ((flags&kGLTextureWrapFlags) == 0) {
		flags |= kGLTextureWrapModeClamp;
	}
	if ((flags&kGLTextureFilterFlags) == 0) {
		flags |= kGLTextureFilterModeLinear;
	}
	return flags;
}

-(id)initWithFile:(NSString *)file {
	self = [self initWithFile: file flags: 0];
	return self;
}

-(void)setTextureModes:(unsigned int)flags {

	
	GLuint sWrap, tWrap;
	if (flags & kGLTextureWrapModeClamp) {
		sWrap = tWrap = GL_CLAMP_TO_EDGE;
	}
	else if (flags & kGLTextureWrapModeRepeat) {
		sWrap = tWrap = GL_REPEAT;
	}
	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, sWrap);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tWrap);
	GLint mag_filter = (flags & kGLTextureFilterModeLinear) ? GL_LINEAR : GL_NEAREST;
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
	
	if (flags & kGLTextureGenerateMipMaps) {
		GLint minfilter = (flags & kGLTextureMipMapTrilinear) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST;
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
		
		//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1);

	}
	else {
		GLint minfilter = (flags & kGLTextureFilterModeLinear) ? GL_LINEAR : GL_NEAREST;
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
		
		//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 0);
	}
}

-(id)initWithFile:(NSString *)file flags:(unsigned int)flags {
	
	
	self = [super init];
	
    CGImageRef spriteImage;
    CGContextRef spriteContext;
    GLubyte *spriteData;
	
	flags = [self enableDefaultFlags: flags];

#if TARGET_OS_IPHONE
	// Creates a Core Graphics image from an image file (autoreleased)
    UIImage *image = [UIImage imageWithContentsOfFile: file];
	if (!image) {
		NSLog(@"Could not open texture %@", file);
		return NULL;
	}
	
	spriteImage = image.CGImage;
#elif TARGET_OS_MAC
	NSImage *image = [[NSImage alloc] initWithContentsOfFile: file];
	if (!image) {
		NSLog(@"Could not open texture %@", file);
		return NULL;
	}
	
	CGImageSourceRef source;
	source		=	CGImageSourceCreateWithData((CFDataRef)[image TIFFRepresentation], NULL);
	spriteImage =  CGImageSourceCreateImageAtIndex(source, 0, NULL);
	[image release];
	CFRelease(source);
		
#endif 
	
    // Get the width and height of the image
    width = CGImageGetWidth(spriteImage);
    height = CGImageGetHeight(spriteImage);
	
	internalWidth = powerOfTwo(width);
	internalHeight = powerOfTwo(height);
	
	GLuint format;
	GLuint bpp;
	CGBitmapInfo bitmapInfo;
	
	if (flags & kGLTextureNoAlphaFlag) {
		format = GL_RGB;
		bpp = 24;
		bitmapInfo = kCGImageAlphaNone;
	}
	else {
		format = GL_RGBA;
		bpp = 32;
		bitmapInfo = kCGImageAlphaPremultipliedLast;		
	}
	
     if(spriteImage) {

        spriteData = (GLubyte *)calloc(internalWidth * internalHeight, bpp / 8);
        spriteContext = CGBitmapContextCreate(spriteData, internalWidth, internalHeight, 8, internalWidth * (bpp / 8), CGImageGetColorSpace(spriteImage), bitmapInfo);
        
		CGContextSetBlendMode(spriteContext, kCGBlendModeCopy);

		CGContextTranslateCTM(spriteContext, 0, height);
		CGContextScaleCTM(spriteContext, 1, -1);
		 
		CGContextDrawImage(spriteContext, CGRectMake(0, internalHeight - height, (CGFloat)width, (CGFloat)height), spriteImage);
        CGContextRelease(spriteContext);
        
        glGenTextures(1, &descriptor);
        glBindTexture(GL_TEXTURE_2D, descriptor);
	
		[self setTextureModes: flags];
		
		glTexImage2D(GL_TEXTURE_2D, 0, format, internalWidth, internalHeight, 0, format, GL_UNSIGNED_BYTE, spriteData);
					
		if ( flags & kGLTextureGenerateMipMaps ) {
			glGenerateMipmap(GL_TEXTURE_2D);	 
		}
		 
        free(spriteData);
		
    } 

	return self;

}

-(id)initWithSize:(CGSize)size flags:(unsigned int)flags {
	
	
	self = [super init];
	
	flags = [self enableDefaultFlags: flags];
	
	width = size.width;
	height = size.height;
	internalWidth = powerOfTwo(width);
	internalHeight = powerOfTwo(height);

	glGenTextures(1, &descriptor);
	glBindTexture(GL_TEXTURE_2D, descriptor);

	GLuint format;
	if (flags & kGLTextureNoAlphaFlag) {
		format = GL_RGB;
	}
	else {
		format = GL_RGBA;
	}
	
	glTexImage2D(GL_TEXTURE_2D, 0, format, internalWidth, internalHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	[self setTextureModes: flags];
	
	return self;
	
}

-(void)dealloc {
	glDeleteTextures(1, &descriptor);
	[super dealloc];
}


@end
